import nodemailer from 'nodemailer';
import redisClient from '../utils/redis.js';

// 邮件传输器配置（建议放独立配置文件）
const transport = nodemailer.createTransport({
  host: 'smtp.qq.com',
  port: 465,
  secure: true,
  auth: {
    user: process.env.QQ_EMAIL,
    pass: process.env.QQ_AUTH_CODE
  }
});


// 验证码生成方案
// 验证码生成与频率限制方案
async function generateCode(ctx) {
  const { email } = ctx.query;
  const ip = ctx.request.ip;
  console.log('%c [ ip ]-21', 'font-size:13px; background:pink; color:#bf2c9f;', ip)

  // 频率限制键名定义
  const emailLimitKey = `captcha_limit:email:${email}`;
  // const ipLimitKey = `captcha_limit:ip:${ip}`;

  try {
    // 双重频率检查（邮箱+IP）
    const [emailCount, ipCount] = await Promise.all([
      redisClient.get(emailLimitKey),
      // redisClient.get(ipLimitKey)
    ]);

    // 邮箱请求限制（示例：5次/小时）
    if (parseInt(emailCount) >= 5) {
      throw new Error('该邮箱请求过于频繁，请稍后再试');
    }

    // IP请求限制（示例：20次/小时）
    if (parseInt(ipCount) >= 20) {
      throw new Error('当前IP请求过于频繁，请稍后再试');
    }

    // 生成验证码
    const code = Math.floor(100000 + Math.random() * 900000).toString();

    // 使用事务保证原子性操作
    const multi = redisClient.multi()
      .set(`captcha:${email}`, JSON.stringify({
        code: code,
        ip: ip,
        attempts: 0
      }), 180)
      .incr(emailLimitKey)
    // .incr(ipLimitKey);

    // 首次设置过期时间（避免重复设置）
    if (!emailCount) multi.expire(emailLimitKey, 360);
    // if (!ipCount) multi.expire(ipLimitKey, 3600);

    await multi.exec();

    return code;
  } catch (err) {
    // 异常处理
    console.error('验证码生成失败:', err.message);
    throw err;
  }
}

// 增强的邮件发送逻辑
const email_reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
// 发送短信验证码
export const sendEmailCode = async (ctx) => {
  let { email, accessToken } = ctx.query;
  // 验证临时令牌,如果令牌不通过不予以发送邮件
  const isValid = await redisClient.exists(`access:${accessToken}`);
  if (!isValid) {
    reject("请先完成图形验证");
    return;
  }
  // 生成验证码
  const code = await generateCode(ctx);
  await redisClient.set(`verification:${email}`, code, 180);//把验证码存到redis
  return new Promise((resolve, reject) => {
    if (email_reg.test(email)) {
      //邮箱验证通过
      transport.sendMail(
        {
          from: process.env.QQ_EMAIL, // 发件邮箱,和初始化代码中的user一样
          to: email, // 收件人
          subject: "验证你的电子邮件", // 标题
          html: `
          <table width="100%" cellpadding="0" cellspacing="0" style="max-width: 600px; margin: 0 auto; font-family: Arial, sans-serif; background-color: #ffffff; border: 1px solid #e0e0e0; border-radius: 8px; overflow: hidden;">
  <!-- 头部 -->
  <tr>
    <td style="padding: 20px; background-color: #0073e6; color: #ffffff; text-align: center;">
      <h1 style="margin: 0; font-size: 24px;">小梁博客系统</h1>
    </td>
  </tr>

  <!-- 正文 -->
  <tr>
    <td style="padding: 20px;">
      <p style="font-size: 16px; color: #333; line-height: 1.6;">你好！</p>
      <p style="font-size: 16px; color: #333; line-height: 1.6;">您正在小梁博客系统进行邮箱验证。</p>
      <p style="font-size: 16px; color: #333; line-height: 1.6;">你的验证码是：</p>
      <div style="text-align: center; margin: 20px 0;">
        <span style="display: inline-block; padding: 10px 20px; font-size: 24px; font-weight: bold; color: #ffffff; background-color: #ff4e2a; border-radius: 4px;">
          ${code}
        </span>
      </div>
      <p style="font-size: 14px; color: #999; text-align: center;">***该验证码3分钟内有效***</p>
    </td>
  </tr>

  <!-- 底部 -->
  <tr>
    <td style="padding: 20px; background-color: #f7f7f7; text-align: center;">
      <p style="font-size: 14px; color: #999; margin: 0;">如有疑问，请联系我们：<a href="mailto:support@xiaoliang.com" style="color: #0073e6; text-decoration: none;">support@xiaoliang.com</a></p>
    </td>
  </tr>
</table>`, // html 内容
        },
        function (err, data) {
          if (err) {
            console.log("发送验证码失败！", err);
            reject("发送邮箱验证码失败");
            transport.close(); //关闭连接池
          } else {
            resolve("发送成功,请在邮箱中查收!");
          }
        }
      );
    } else {
      console.log("邮箱格式错误！");
      reject("emailFormat error");
    }
  });
};